/*
 * Copyright (c) 2009, Servoy-stuff
 * 
 * This library is free software; you can redistribute it and/or modify it under
 * the terms of the GNU Lesser General Public License as published by the Free
 * Software Foundation; either version 2.1 of the License, or (at your option)
 * any later version.
 * 
 * This library is distributed in the hope that it will be useful, but WITHOUT
 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
 * FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more
 * details.
 * 
 * You should have received a copy of the GNU Lesser General Public License
 * along with this library; if not, write to the Free Software Foundation, Inc.,
 * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
 * http://www.fsf.org/licensing/licenses/lgpl.txt
 */
package net.stuff.servoy.beans.calendar.swing;

import java.awt.Color;
import java.awt.Insets;
import java.awt.KeyboardFocusManager;
import java.awt.event.ActionEvent;
import java.awt.event.FocusEvent;
import java.text.DateFormat;
import java.text.ParseException;
import java.util.Calendar;
import java.util.Date;

import javax.swing.UIManager;
import javax.swing.border.EmptyBorder;
import javax.swing.event.CaretEvent;

import com.servoy.j2db.Messages;
import com.toedter.calendar.JTextFieldDateEditor;

/**
 * A specialisation of the JTextFieldDateEditor to make the control "Servoy Aware"
 * 
 * @version 1.0.1 - 2009-06-01 - Added Time controls
 * @author Servoy-stuff
 * http://www.servoy-stuff.net/
 */
public class JModifiedTextFieldEditor extends JTextFieldDateEditor {
	
	public Color errorColor = Color.RED;
	public Color validColor = new Color(0, 150, 0);

	/**
	 * 
	 */
	private static final long serialVersionUID = 8647021917696854943L;
	private boolean validationMode = true;
	
	/**
	 * Constuctor
	 */
	public JModifiedTextFieldEditor() {
		super();
		setFocusTraversalKeysEnabled(false);
		super.setFocusTraversalKeysEnabled(false);
		setBorder(new EmptyBorder(new Insets(0,0,0,0)));
	}
	
	
	/* (non-Javadoc)
	 * @see com.toedter.calendar.JTextFieldDateEditor#focusLost(java.awt.event.FocusEvent)
	 */
	@Override
	public void focusLost(FocusEvent e) {
		textCheck();
	}
		
	/* (non-Javadoc)
	 * @see com.toedter.calendar.JTextFieldDateEditor#focusGained(java.awt.event.FocusEvent)
	 */
	@Override
	public void focusGained(FocusEvent e) {
		if (getUiComponent().equals(e.getOppositeComponent())) {
			KeyboardFocusManager.getCurrentKeyboardFocusManager().upFocusCycle();
		}
	}
	
	/* (non-Javadoc)
	 * @see com.toedter.calendar.JTextFieldDateEditor#actionPerformed(java.awt.event.ActionEvent)
	 */
	@Override
	public void actionPerformed(ActionEvent e) {
		textCheck();
	}
	
	
	/* (non-Javadoc)
	 * @see com.toedter.calendar.JTextFieldDateEditor#caretUpdate(javax.swing.event.CaretEvent)
	 */
	@Override
	public void caretUpdate(CaretEvent event) {
		if (!validationMode || !isEditable() || !isEnabled()) {
			setForeground(UIManager.getColor("TextField.foreground"));
			setValid();
			return;
		}
		
		String text = getText().trim();
		String emptyMask = maskPattern.replace('#', placeholder);

		if (text.length() == 0 || text.equals(emptyMask)) {
			setForeground(UIManager.getColor("TextField.foreground"));
			return;
		}

		try {
			Date date = dateFormatter.parse(getText());
			if (dateUtil.checkDate(date)) {
				setForeground((validColor == null) ? darkGreen : validColor);
				setValid();
			} else {
				setForeground((errorColor == null) ? Color.RED : errorColor);
				setInvalid();
			}
		} catch (Exception e) {
			setForeground((errorColor == null) ? Color.RED : errorColor);
			setInvalid();
		}
	}
	
	
	/**
	 * Check the validity of the typed text against the set format.
	 * Only in validation mode
	 */
	public void textCheck() {
		if (validationMode) {
			try {
				String s = getText();
				if (s != null && s.trim().length() > 0) {
					Date date = dateFormatter.parse(s);
					super.setDate(date, true);
				} else {
					setValid();
					super.setDate(null, true);
				}
			} catch (Exception e) {
				// ignore
			}
		}
	}
	
	
	/* (non-Javadoc)
	 * @see com.toedter.calendar.JTextFieldDateEditor#setDate(java.util.Date, boolean)
	 */
	@Override
	public void setDate(Date date, boolean firePropertyChange) {
		super.setDate(date, firePropertyChange);
	}
	

	/* (non-Javadoc)
	 * @see com.toedter.calendar.JTextFieldDateEditor#getDate()
	 */
	@Override
	public Date getDate() {
		// override this method because we need to take the Time into account
		try {
			Calendar calendar = Calendar.getInstance();
			calendar.setTime(dateFormatter.parse(getText()));
			date = calendar.getTime();
		} catch (ParseException e) {
			date = null;
		}
		return date;
	}
	
	public void setDateFormatString(String dateFormatString) {
		super.setDateFormatString(dateFormatString);
		SwingDateChooser sdc = (SwingDateChooser)getParent();
		if (sdc != null) {
			String t = sdc.getToolTipText();
			if (t != null) {
				setToolTipText(Messages.getStringIfPrefix(t));
			}
		}
	}


	/**
	 * @return the validationMode
	 */
	public boolean isValidationMode() {
		return this.validationMode;
	}

	/**
	 * @param validationMode the validationMode to set
	 */
	public void setValidationMode(boolean validationMode) {
		this.validationMode = validationMode;
	}

	/**
	 * @return the validColor
	 */
	public Color getValidColor() {
		return validColor;
	}

	/**
	 * @param validColor the validColor to set
	 */
	public void setValidColor(Color validColor) {
		this.validColor = validColor;

	}

	/**
	 * @return the errorColor
	 */
	public Color getErrorColor() {
		return errorColor;
	}

	/**
	 * @param errorColor the errorColor to set
	 */
	public void setErrorColor(Color errorColor) {
		this.errorColor = errorColor;
	}

	/**
	 * @return the dateFormatter
	 */
	public DateFormat getDateFormatter() {
		return dateFormatter;
	}

	/* (non-Javadoc)
	 * @see javax.swing.text.JTextComponent#setEditable(boolean)
	 */
	@Override
	public void setEditable(boolean b) {
		super.setEditable(b);
		super.setBackground(UIManager.getColor("TextField.background"));
		super.setForeground(UIManager.getColor("TextField.foreground"));
	}
	
	/**
	 * Set the valid state of this component
	 */
	private void setValid() {
		((SwingDateChooser)getParent()).setValid();
	}
	
	/**
	 * Set the invalid state of this component
	 */
	private void setInvalid() {
		((SwingDateChooser)getParent()).setInvalid();
	}
}
